package cn.goktech.controller;

import cn.goktech.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

@Controller
@SessionAttributes(value = {"user1"})
public class ModelArrContronller {

    /**
     * @ModelAttribute 被注解的方法会在每个RequestMapping执行之前先执行
     */
    @ModelAttribute
    public void modelArr(Model model) {
        System.out.println("这是被@ModelAttribute注解的方法");
        model.addAttribute("str", "hello");
        model.addAttribute("id", "defaultString");
        // model.addAttribute("user", new User(103, "admin", "bobo"));
    }

    /**
     * @ModelAttribute 在方法中没有model存放数据，方法中的返回数据也会被存放到作用域中
     * 向model中添加的键值对的 key为返回值类型的首字母小写字符串， value值为返回的数据
     * 也可以在@ModelAttribute中指定 key的名字
     */
  /*  @ModelAttribute（”user“）
    public User modelArr() {
        System.out.println("这是被@ModelAttribute注解的方法");
        return new User();
    }*/
    @RequestMapping("/test")
    public String test() {
        System.out.println("这是test中的方法");
        return "model3";
    }

    /**
     * ModelAttribute 注解在方法参数中
     * 1、表示从模型（model）中取值指定对象 赋值给型参
     * 2、如果模型中不存在，参数会首先被实例化，然后添加到模型中，然后再赋值给形参。
     * 3、如果该请求url中携带与参数名一样的参数，也会被模型（model）中覆盖
     */
    @RequestMapping("/test2")
    public String test2(@ModelAttribute("id") String id) {

        System.out.println("id=" + id);
        return "model3";
    }

    @RequestMapping("/test3")
    public String test3(@ModelAttribute("user") User user) {

        System.out.println("user=" + user);
        return "model3";
    }

    @RequestMapping("/test4")
    public String test4() {
        return "model3";
    }

    /**
     * 移除session数据
     *
     * @param sessionStatus
     * @return
     */
    @RequestMapping("/removeSessionAttributes")
    public String removeSessionAttributes(SessionStatus sessionStatus) {
        sessionStatus.setComplete();
        return "success";
    }

    /**
     *@ModelAttribute所修饰的方法参数，会做一下的查找
     * 1、先在model中查找是否有对应的数据，如果没有的话
     * 2、在根据在类是否被@SessionAttributes修饰，如果有
     * 3、去session做查找相同的key，此时session中不存在则抛异常，
     *
     * 解决方式：
     * 1、@ModelAttribute（key）与@SessionAttributes(value = {key})两者的key取不同的名字
     * 2、如果key一样的话，避免抛异常，则需要在某个方法前添加@ModelAttribute，提前在方法内部存放key的数据
     *
     */
    @RequestMapping("/test5")
    public String test5(@ModelAttribute("user1") User user) {
        System.out.println(user);
        return "model3";
    }
}
